package cn.com.easy.pay.weixinpay.controller;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.web.bind.annotation.RequestMapping;

import cn.com.easy.dto.MessageDTO;
import cn.com.easy.exception.BusinessException;
import cn.com.easy.pay.weixinpay.config.WeixinPayConfig;
import cn.com.easy.utils.ResponseOutputUtils;

import com.tencent.business.DownloadBillBusiness;
import com.tencent.business.DownloadBillBusiness.ResultListener;
import com.tencent.common.Configure;
import com.tencent.protocol.downloadbill_protocol.DownloadBillReqData;
import com.tencent.protocol.downloadbill_protocol.DownloadBillResData;

/**
 * 微信下载对账单基础控制器
 * 
 * @author nibili 2017年5月14日
 * 
 */
public abstract class WeixinPayDownloadBillBaseController {

	private Logger logger = LoggerFactory.getLogger(WeixinPayDownloadBillBaseController.class);

	/** 对账单下载服务类 ，sdk */
	private DownloadBillBusiness downloadBillBusiness;

	/**
	 * 获取微信支付配置<br/>
	 * 
	 * @param httpRequest
	 * @return
	 * @throws BusinessException
	 * @author nibili 2017年5月12日
	 */
	public abstract WeixinPayConfig getWeixinPayConfig(HttpServletRequest httpRequest) throws BusinessException;

	/**
	 * 获取下载对账单所需配置
	 * 
	 * @param httpRequest
	 * @throws BusinessException
	 * @author nibili 2017年5月14日
	 */
	public abstract DownloadBillReqData getDownloadBillReqData(HttpServletRequest httpRequest) throws BusinessException;

	@RequestMapping("/reverse")
	public void payQuery(final HttpServletRequest request, final HttpServletResponse response, String outTradeNo) {
		try {

			WeixinPayConfig weixinPayConfig = getWeixinPayConfig(request);
			Configure configure = new Configure();
			configure.setKey(weixinPayConfig.getAppkey());
			configure.setAppID(weixinPayConfig.getAppid());
			configure.setMchID(weixinPayConfig.getMch_id());
			configure.setSubMchID(weixinPayConfig.getSubMchID());
			configure.setCertLocalPath(weixinPayConfig.getCertLocalPath());
			configure.setCertPassword(weixinPayConfig.getCertPassword());
			downloadBillBusiness = new DownloadBillBusiness(configure);
			//
			DownloadBillReqData downloadBillReqData = getDownloadBillReqData(request);
			downloadBillBusiness.run(downloadBillReqData, new ResultListener() {

				@Override
				public void onFailByReturnCodeError(DownloadBillResData downloadBillResData) {
					WeixinPayDownloadBillBaseController.this.onFailByReturnCodeError(request, response, downloadBillResData);
				}

				@Override
				public void onFailByReturnCodeFail(DownloadBillResData downloadBillResData) {
					WeixinPayDownloadBillBaseController.this.onFailByReturnCodeFail(request, response, downloadBillResData);
				}

				@Override
				public void onDownloadBillFail(String responseString) {
					WeixinPayDownloadBillBaseController.this.onDownloadBillFail(request, response, responseString);
				}

				@Override
				public void onDownloadBillSuccess(String responseString) {
					WeixinPayDownloadBillBaseController.this.onDownloadBillSuccess(request, response, responseString);
				}

			});

		} catch (BusinessException ex) {
			logger.error("撤销订单发生异常(自定义异常):" + ex.getMessage(), ex);
			// 错误
			ResponseOutputUtils.renderJson(response, MessageDTO.newInstance("", false, ex.getMessage()));
		} catch (Exception ex) {
			logger.error("撤销订单发生异常:" + ex.getMessage(), ex);
			// 错误
			ResponseOutputUtils.renderJson(response, MessageDTO.newInstance("", false, ex.getMessage()));
		}
	}

	/**
	 * API返回ReturnCode不合法，支付请求逻辑错误，请仔细检测传过去的每一个参数是否合法，或是看API能否被正常访问 <br/>
	 * 例：请检查每一个参数是否合法
	 * 
	 * @param request
	 * @param response
	 * @param reverseResData
	 * @author nibili 2017年5月13日
	 */
	public abstract void onFailByReturnCodeError(HttpServletRequest request, HttpServletResponse response, DownloadBillResData downloadBillResData);

	/**
	 * API返回ReturnCode为FAIL，支付API系统返回失败，请检测Post给API的数据是否规范合法 <br/>
	 * 例 ： 请检测Post给API的数据是否规范合法
	 * 
	 * @param request
	 * @param response
	 * @param reverseResData
	 * @author nibili 2017年5月13日
	 */
	public abstract void onFailByReturnCodeFail(HttpServletRequest request, HttpServletResponse response, DownloadBillResData downloadBillResData);

	/**
	 * 下载对账单失败<br/>
	 * 例：
	 * 
	 * @param request
	 * @param response
	 * @param responseString
	 * @author nibili 2017年5月14日
	 */
	public abstract void onDownloadBillFail(HttpServletRequest request, HttpServletResponse response, String responseString);

	/**
	 * 下载对账单成功
	 * 
	 * @param request
	 * @param response
	 * @param responseString
	 * @author nibili 2017年5月14日
	 */
	public abstract void onDownloadBillSuccess(HttpServletRequest request, HttpServletResponse response, String responseString);

}
